﻿using WMS.FC.Domain.DomainObject.System;
using WMS.FC.Domain.Repository;
using WMS.FC.Infrastructure.Common;

namespace WMS.FC.Infrastructure.Repository
{
    public class UnitOfWork : IUnitOfWork
    {
        protected readonly WmsDbContext wmsDbContext;

        public UnitOfWork(WmsDbContext wmsDbContext)
        {
            this.wmsDbContext = wmsDbContext;
        }

        public async Task<ActionResult<List<T>>> UseTranAsync<T>(Func<Task<ActionResult<List<T>>>> action) where T : DomainObjectBase
        {
            var result = new ActionResult<List<T>>(null);
            try
            {
                await wmsDbContext.Database.BeginTransactionAsync();
                result = await action();
                if (result.IsSuccess)
                    await wmsDbContext.Database.CommitTransactionAsync();
                else
                    await wmsDbContext.Database.RollbackTransactionAsync();
            }
            catch (Exception ex)
            {
                await wmsDbContext.Database.RollbackTransactionAsync();
                result = result.Exception(ex);
            }

            return result;
        }

        public async Task<ActionResult<T>> UseTranAsync<T>(Func<Task<ActionResult<T>>> action) where T : DomainObjectBase
        {
            var result = new ActionResult<T>(null);
            try
            {
                await wmsDbContext.Database.BeginTransactionAsync();
                result = await action();
                if (result.IsSuccess)
                    await wmsDbContext.Database.CommitTransactionAsync();
                else
                    await wmsDbContext.Database.RollbackTransactionAsync();
            }
            catch (Exception ex)
            {
                await wmsDbContext.Database.RollbackTransactionAsync();
                result = result.Exception(ex);
            }

            return result;
        }

        public async Task<ActionResult<string>> UseTranAsync(Func<Task<ActionResult<string>>> action)
        {
            var result = new ActionResult<string>(null);
            try
            {
                await wmsDbContext.Database.BeginTransactionAsync();
                result = await action();
                if (result.IsSuccess)
                    await wmsDbContext.Database.CommitTransactionAsync();
                else
                    await wmsDbContext.Database.RollbackTransactionAsync();
            }
            catch (Exception ex)
            {
                await wmsDbContext.Database.RollbackTransactionAsync();
                result = result.Exception(ex);
            }

            return result;
        }

        public async Task<ActionResultBase> UseTranAsync(Func<Task<ActionResultBase>> action)
        {
            var result = new ActionResultBase(null);
            try
            {
                await wmsDbContext.Database.BeginTransactionAsync();
                result = await action();
                if (result.IsSuccess)
                    await wmsDbContext.Database.CommitTransactionAsync();
                else
                    await wmsDbContext.Database.RollbackTransactionAsync();
            }
            catch (Exception ex)
            {
                await wmsDbContext.Database.RollbackTransactionAsync();
                result = result.Exception(ex);
            }

            return result;
        }

        public async Task BeginTransactionAsync()
        {
            await wmsDbContext.Database.BeginTransactionAsync();
        }

        public async Task CommitTransactionAsync()
        {
            await wmsDbContext.Database.CommitTransactionAsync();
        }

        public async Task RollbackTransactionAsync()
        {
            await wmsDbContext.Database.RollbackTransactionAsync();
        }
    }
}
